<?php
class ControllerPaymentOfflineCC extends Controller {

	private $name = '';
	protected $errors = array();

	protected function index() {
	
		$this->name = basename(__FILE__, '.php');

		$this->data = array_merge($this->data, $this->load->language('payment/' . $this->name));

		$this->data['cards'] = array();
		$this->data['cards'][] = array('text'  => 'Visa', 'value' => 'VISA');
		$this->data['cards'][] = array('text'  => 'MasterCard', 'value' => 'MASTERCARD');
		$this->data['cards'][] = array('text'  => 'Discover Card', 'value' => 'DISCOVER');
		$this->data['cards'][] = array('text'  => 'American Express','value' => 'AMEX');
		
		$this->data['months'] = array();
		for ($i = 1; $i <= 12; $i++) {
			$this->data['months'][] = array(
				'text'  => sprintf('%02d', $i), 
				'value' => sprintf('%02d', $i)
			);
		}
		
		$today = getdate();
		$this->data['year_expire'] = array();
		for ($i = $today['year']; $i < $today['year'] + 11; $i++) {
			$this->data['year_expire'][] = array(
				'text'  => date("Y", mktime(0, 0, 0, 1, 1, $i)),
				'value' => date("y", mktime(0, 0, 0, 1, 1, $i)) 
			);
		}
		
		$this->data['error'] 			= (isset($this->session->data['error'])) ? $this->session->data['error'] : NULL;
		$this->data['text_creditcard'] 	= $this->language->get('text_creditcard');
		$this->data['entry_cc_type'] 	= $this->language->get('entry_cc_type');
		$this->data['entry_cc_name'] 	= $this->language->get('entry_cc_name');
		$this->data['entry_cc_number'] 	= $this->language->get('entry_cc_number');
		$this->data['entry_cc_expire'] 	= $this->language->get('entry_cc_expire');
		$this->data['entry_cc_cvv']  	= $this->language->get('entry_cc_cvv');
		$this->data['cc_type_val'] 		= (isset($this->session->data['cc_type'])) ? $this->session->data['cc_type'] : NULL;
		$this->data['cc_name_val'] 		= (isset($this->session->data['cc_name'])) ? $this->session->data['cc_name'] : NULL;
		$this->data['cc_number_val'] 	= (isset($this->session->data['cc_number'])) ? $this->session->data['cc_number'] : NULL;
		$this->data['cc_month_val'] 	= (isset($this->session->data['cc_month'])) ? $this->session->data['cc_month'] : NULL;
		$this->data['cc_year_val'] 		= (isset($this->session->data['cc_year'])) ? $this->session->data['cc_year'] : NULL;
		$this->data['cc_cvv_val'] 		= (isset($this->session->data['cc_cvv'])) ? $this->session->data['cc_cvv'] : NULL;

		unset($this->session->data['error']);
		unset($this->session->data['cc_type']);
		unset($this->session->data['cc_name']);
		unset($this->session->data['cc_number']);
		unset($this->session->data['cc_month']);
		unset($this->session->data['cc_year']);
		unset($this->session->data['cc_cvv']);

		if (file_exists(DIR_TEMPLATE . $this->config->get('config_template') . '/template/payment/' . $this->name . '.tpl')) {
            $this->template = $this->config->get('config_template') . '/template/payment/' . $this->name . '.tpl';
        } else {
            $this->template = 'default/template/payment/' . $this->name . '.tpl';
        }

		$this->render();
	}

	public function confirm() {
		$order_id = $this->session->data['order_id'];
		$ccType = $this->request->post['cc_type'];
		$ccName = $this->request->post['cc_name'];
		$ccNumber = preg_replace('/[^0-9 -]/', '', $this->request->post['cc_number']); // strip non numerics from the text but leave spaces for the moment.
		$ccMonth = $this->request->post['cc_month'];
		$ccYear = $this->request->post['cc_year'];
		$ccCVV = $this->request->post['cc_cvv'];
		
		$message  = 'Order ID: ' . $order_id . " \n\n" ;
		$message .= 'Card Type: ' . $ccType . " \n" ;
		$message .= 'Card Owner: ' . $ccName . " \n" ;
		$message .= 'Card Number: ' . $ccNumber . " \n" ; 
		$message .= 'Expiry Month: ' . $ccMonth . " \n" ; 
		$message .= 'Expiry Year: ' . $ccYear . " \n" ;
		$message .= 'CCV: ' . $ccCVV . " \n" ;
		
		$json = array();
		if (!$this->validateForm()) {
			$json['error'] = $this->errors[0];
		} else {
			$this->load->model('checkout/order');
			$order_info = $this->model_checkout_order->getOrder($order_id);
			$this->model_checkout_order->confirm($order_id, $this->config->get($this->name . '_order_status_id'));
			$this->model_checkout_order->update($order_id, $this->config->get($this->name . '_order_status_id'), $message, false);
			
			//Admin Alert Mail
			if ($this->config->get('config_alert_mail')) {
				$subject = sprintf('%s - Order %s - Offline Card', html_entity_decode($this->config->get('config_name'), ENT_QUOTES, 'UTF-8'), $order_id);
			
				$mail = new Mail(); 
				$mail->protocol = $this->config->get('config_mail_protocol');
				$mail->parameter = $this->config->get('config_mail_parameter');
				$mail->hostname = $this->config->get('config_smtp_host');
				$mail->username = $this->config->get('config_smtp_username');
				$mail->password = $this->config->get('config_smtp_password');
				$mail->port = $this->config->get('config_smtp_port');
				$mail->timeout = $this->config->get('config_smtp_timeout');
				$mail->setTo($this->config->get('config_email'));
				$mail->setFrom($this->config->get('config_email'));
				$mail->setSender($order_info['store_name']);
				$mail->setSubject($subject);
				$mail->setText($message);
				$mail->send();
				
				// Send to additional alert emails
				$emails = explode(',', $this->config->get('config_alert_emails'));
				
				foreach ($emails as $email) {
					if ($email && preg_match('/^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,3})$/i', $email)) {
						$mail->setTo($email);
						$mail->send();
					}
				}				
			}
			
			$json['success'] = $this->url->link('checkout/success');		
		}
		
		$this->load->library('json');
		
		$this->response->setOutput(Json::encode($json));
	}
	
	
    private function validateForm() {
		$this->name = basename(__FILE__, '.php');
        $this->load->language('payment/' . $this->name);

        // Save the fields to the session for repopulation
        $this->session->data['cc_type'] = $this->request->post['cc_type'];
        $this->session->data['cc_name'] = $this->request->post['cc_name'];
        $this->session->data['cc_number'] = $this->request->post['cc_number'];
        $this->session->data['cc_month'] = $this->request->post['cc_month'];
        $this->session->data['cc_year'] = $this->request->post['cc_year'];
        $this->session->data['cc_cvv'] = $this->request->post['cc_cvv'];
        $this->errors = array();
        $ccType = $this->request->post['cc_type'];
        $ccNumber = preg_replace('/[^0-9 -]/', '', $this->request->post['cc_number']); // strip non numerics from the text but leave spaces.
        $ccMonth = $this->request->post['cc_month'];
        $ccYear = $this->request->post['cc_year'];
        $ccCVV = $this->request->post['cc_cvv'];

        if (strlen($this->request->post['cc_name']) == 0) {
         	$this->errors[] = $this->language->get('error_cc_name_missing');
        }

        if (strlen($ccNumber) == 0) {
            $this->errors[] = $this->language->get('error_cc_number_missing');
        } elseif (strlen($ccNumber) <> strlen($this->request->post['cc_number'])) {
            $this->errors[] = $this->language->get('error_cc_number_not_numeric');
        }

        if (strlen($ccMonth) == 0) {
            $this->errors[] = $this->language->get('error_cc_month_missing');
        }

        if (strlen($ccYear) == 0) {
            $this->errors[] = $this->language->get('error_cc_year_missing');
        }

        if (strlen($ccCVV) == 0) {
            $this->errors[] = $this->language->get('error_cc_cvv_missing');
        }

        //  No point to continue validating if we already have an error.
        if (count($this->errors) > 0) {
            return false;
        }

        //  now we remove spaces & dashes from the credit card number so that we can test it as a number.
        $ccNumber = preg_replace('/[ -]/', '', $ccNumber);

        //  and remove all non numerics from the following and validate them.
        $ccMonth = preg_replace('/[^0-9]/', '', $ccMonth);
        $ccYear = preg_replace('/[^0-9]/', '', $ccYear);

        if (strlen($ccMonth) <> strlen($this->request->post['cc_month'])) {
            $this->errors[] = $this->language->get('error_cc_month_not_numeric');
        }
        if (strlen($ccYear) <> strlen($this->request->post['cc_year'])) {
            $this->errors[] = $this->language->get('error_cc_year_not_numeric');
        }

        //  No point to continue validating if we already have an error.
        if (count($this->errors) > 0) {
            return false;
        }

        //  Valid credit card number ?
        $cardNumber = strrev($ccNumber);
        $numSum = 0;
        for($i = 0; $i < strlen($cardNumber); $i++) {
            $currentNum = substr($cardNumber, $i, 1);

            // Double every second digit
            if ($i % 2 == 1) {
                $currentNum *= 2;
            }

            // Add digits of 2-digit numbers together
            if ($currentNum > 9) {
                $firstNum = $currentNum % 10;
                $secondNum = ($currentNum - $firstNum) / 10;
                $currentNum = $firstNum + $secondNum;
            }
            $numSum += $currentNum;
        }
        if ($numSum % 10 != 0) {
            $this->errors[] = $this->language->get('error_cc_number_invalid');
            return false;
        }
		
        // Month must be in the range 1 to 12
        $ccMonth = (int)$ccMonth;
        if ($ccMonth < 1 || $ccMonth > 12) {
            $this->errors[] = $this->language->get('error_cc_month_invalid_range');
        }

        // Year cannot be more than 10 years into the future
        $ccYear = (int)$ccYear;
        $currentYear = (int)date('y');
        if ($ccYear  > $currentYear + 10) {
            $this->errors[] = $this->language->get('error_cc_year_invalid_range');
        }

        // Cannot expire within the next 3 days because the payment is processed on weekdays and it could be friday night
        $margin = 3;
        // $margin days before the 1st day of the month after ValidTo date on card
        $ccExpiresLimit = mktime(0,0,0, $ccMonth + 1,  1 - $margin, $ccYear);
        $today = mktime(0,0,0);
        if ($today >= mktime(0,0,0, $ccMonth + 1,  1, $ccYear)) {
            $this->errors[] = $this->language->get('error_cc_expired');
        } else if ($today >= $ccExpiresLimit) {
            $this->errors[] = $this->language->get('error_cc_expires_too_soon');
        }

        return (count($this->errors) == 0);
    }
}
?>